package com.spsa.negocio.servicios;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.ejb.EJB;
import javax.ejb.Stateless;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import com.spsa.excepciones.EstadoIlegalExcepcion;
import com.spsa.excepciones.GuardarDatosException;
import com.spsa.excepciones.ServicioException;
import com.spsa.negocio.utilidades.SingletonDatos;
import com.spsa.negocio.utilidades.UtilArchivos;
import com.spsa.persistencia.dao.ReporteDao;
import com.spsa.persistencia.entidades.EstadoInterfaz;
import com.spsa.persistencia.entidades.Interfaz;
import com.spsa.persistencia.entidades.Reporte;
import com.spsa.persistencia.entidades.Tienda;

/**
 * Session Bean implementation class ServicioReporte
 */
@Stateless
public class ServicioGeneracionReportes {

	static final Logger logger = LogManager.getLogger(ServicioGeneracionReportes.class.getName());

	@EJB
	private SingletonDatos singletonDatos;
	@EJB
	private ServicioEstadosTiendas servicioEstadoTiendas;
	@EJB
	private ReporteDao reporteDao;

	public List<Reporte> generarReporteEstadoTiendas() throws ServicioException{
		try {
			List<Reporte> reportes = new ArrayList<Reporte>();
			List<Interfaz> interfaces = singletonDatos.getInterfaces();
			List<EstadoInterfaz> estadosInterfaces = null;

			for (int i = 0; i < interfaces.size(); i++) {
				estadosInterfaces = servicioEstadoTiendas.listarPorInterfaz(interfaces.get(i));
				int numeroTiendasRojo = servicioEstadoTiendas.obtenerCantidadTiendasRojo(estadosInterfaces);

				if (numeroTiendasRojo != 0) {
					Reporte reporte = crearReporte(estadosInterfaces, interfaces.get(i));
					reportes.add(reporte);
				}
			}

			guardarReportesEnBD(reportes);
			return reportes;
		}
		catch(GuardarDatosException e) {
			throw new ServicioException("No se pudo guardar los reportes en la BD");
		}
		catch(ServicioException e) {
			throw e;
		}
	}

	private void guardarReportesEnBD(List<Reporte> reportes) throws GuardarDatosException{
		for (int i = 0; i < reportes.size(); i++) {
			reporteDao.guardar(reportes.get(i));
		}
	}

	public Reporte crearReporte(List<EstadoInterfaz> estados, Interfaz interfaz) throws ServicioException {
		try {
			File archivoReporte = crearArchivoReporte(estados, interfaz);
			Reporte reporte = new Reporte();
			reporte.setFecha(new Date());
			reporte.setInterfaz(interfaz);
			reporte.setArchivo(UtilArchivos.convertirBytes(archivoReporte));
			return reporte;
		} catch (IOException e) {
			logger.fatal("No se pudo crear el archivo de un reporte. Interfaz: " + interfaz, e);
			throw new ServicioException("No se pudo crear el archivo del reporte");
		} catch(EstadoIlegalExcepcion e) {
			logger.fatal(e.getMessage(), e);
			throw new ServicioException(e.getMessage());
		}
		
	}

	private File crearArchivoReporte(List<EstadoInterfaz> estadosInterfaces, Interfaz interfaz) throws IOException
		, EstadoIlegalExcepcion{

		File archivoReporte = new File(interfaz.getRutaReporte());
		FileWriter escritor = new FileWriter(archivoReporte);
		PrintWriter formateador = new PrintWriter(escritor);

		formateador.println("           REPORTE DE TIENDAS EN ROJO\n");
		formateador.println("Interfaz: " + estadosInterfaces.get(0).getDescripcionInterfaz());
		formateador.println("Fecha: " + new Date());
		formateador.println();
		formateador.printf("%-9s%-28s%8s\n", "Codigo", "        Tienda", "Archivos");
		formateador.printf("---------------------------------------------\n");

		for (int i = 0; i < estadosInterfaces.size(); i++) {
			EstadoInterfaz estado = estadosInterfaces.get(i);
			
			if(!tiendaEstaActiva(estado.getCodigoTienda()))
				continue;
			
			if (estado.getCondicion() == 1) {
				formateador
						.printf("%-9s%-24s%6d\n", estado.getCodigoTienda(),
								singletonDatos.buscarTienda(estado.getCodigoTienda()).getNombre(),
								estado.getCantidadArchivos());
			}
		}

		escritor.close();

		return archivoReporte;
	}

	private boolean tiendaEstaActiva(String codigoTienda) {
		
		try {
			Tienda tienda = singletonDatos.buscarTienda(codigoTienda);
			return tienda.isActivo();
		} catch (EstadoIlegalExcepcion e) {
			logger.error("No se pudo encontrar la tienda con codigo: " + codigoTienda, e);
			return false;
		}
	}
}
